// pages/devices/index/index.js
import Tools from '../../../utils/tools.js';

const Tls = new Tools();
const app = getApp();
let BLEPeripheralServer = null; //外围服务的服务端
let toSendData = new Uint8Array(10);
Page({
  /**
   * 页面的初始数据
   */
  data: {
    serverIdArr: [], //1356561491
    page: 1,
    uhide: false,
    totalPage: 1,
    deviceNum: 1,
    carousels: [
      { id: 1, url: '/images/carousel/factory1.jpg' },
      { id: 2, url: '/images/carousel/factory1.jpg' },
      { id: 3, url: '/images/carousel/factory1.jpg' },
    ],
    devices: [{ id: '1', name: '门锁', code: 'abcd' }],
    indicatorDots: true,
    autoplay: true,
    interval: 2000, //间隔
    duration: 2000, //持续
    imgWidth: 800,
    imgHeights: [],
    uuid: '',
    token: '',
    textTips:
      '----------------任何意见、建议均可联系在线客服------------------',
    marqueePace: 1, //滚动速度
    marqueeDistance: 0, //初始滚动距离
    size: 14,
    length: 0,
    windowWidth: 0,
    orientation: 'left', //滚动方向
    connectBleName: '申请开锁',
    hasUserInfo: false,
    userInfo: {},
    nickName: '',
    device: '',
    uuid: '',
    deviceId: '',
    serviceId: '',
    marqueeInterval: 20, //时间间隔
  },

  //建立本地作为外围设备的服务端 -- 可创建多个
  createBLEPeripheralServer() {
    var that = this;
    console.log('创建外围设备');
    wx.createBLEPeripheralServer({
      success(res) {
        console.log(res);
        let data = that.data.serverIdArr;
        if (res.server.serverId) {
          //console.log(res.server.serverId)
          if (that.data.serverIdArr.indexOf(res.server.serverId) == -1) {
            data.push(res.server.serverId);
            that.setData({ serverIdArr: [data] });
          }
        }
        BLEPeripheralServer = res.server;
        console.log(BLEPeripheralServer);
        //监听外围设备动态
        that.onBLEPeripheralConnectionStateChanged();
        //取消监听
        // that.offBLEPeripheralConnectionStateChanged();
        //取消监听特征值事件 -- 读
        // that.offCharacteristicReadRequest();
        //关闭当前服务端
        // that.closeBLEPerypheralServer();
        //添加服务
        that.addService();
        //移除服务
        // that.removeService();
      },
      fail(err) {
        console.log(err);
        wx.showToast({
          title: '请打开蓝牙',
          duration: 5000,
        });
      },
    });
  },

  //添加服务
  addService() {
    //-- ok
    var that = this;
    BLEPeripheralServer.addService({
      service: {
        uuid: '0000ff11-0000-1000-8000-00805f9b34fb',
        characteristics: [
          {
            uuid: '0000ff00-0000-1000-8000-00805f9b34fb',
            permission: {
              readable: true, //可读
              writeable: true, //可写
              readEncryptionRequired: true, //加密读请求
              writeEncryptionRequired: true, //加密写请求
            }, //特征值权限
            properties: {
              write: true,
              read: true,
              notify: true, //订阅
              indicate: true, //回包
            },
            // value:ad_data_38,//特征值对应的二进制值
            value: toSendData, //特征值对应的二进制值
            descriptors: [
              {
                uuid: '0000ff01-0000-1000-8000-00805f9b34fb',
                permission: { write: true, read: true },
                value: toSendData, //描述符数据
              },
            ], //描述符数据
          },
        ],
      }, //描述service的object
      success: function (res) {
        console.log(res);
        //开始广播
        that.startAdvertise();
        //开始广播设置定时器
        // timer = setInterval(() => {
        //   that.startAdvertise();
        // }, 1000)
      },
      fail: function (err) {
        console.log(err);
      },
    });
  },

  //监听已连接的设备请求写当前外围设备的特征值事件  -- 写
  onCharacteristicWriteRequest() {
    console.log('监听已连接的设备请求写当前外围设备的特征值事件');
    ////收到该消息后需要立刻调用 writeCharacteristicValue 写回数据，否则主机不会收到响应
    BLEPeripheralServer.onCharacteristicWriteRequest(function (res) {
      console.log(res);
      //serviceId characteristicId  callbackId
      //callbackId 唯一标识码，调用 writeCharacteristicValue 时使用
      //value 请求写入的特征值数据
    });
  },

  //监听已连接的设备请求读当前外围设备的特征值事件  --读
  onCharacteristicReadRequest() {
    console.log('监听已连接的设备请求读当前外围设备的特征值事件');
    //收到该消息后需要立刻调用 writeCharacteristicValue 写回数据，否则主机不会收到响应
    BLEPeripheralServer.onCharacteristicReadRequest(function (res) {
      console.log(res);
      //serviceId characteristicId  callbackId
      //callbackId 唯一标识码，调用 writeCharacteristicValue 时使用
    });
  },

  //取消监听已连接的设备请求读当前外围设备的特征事件 -- 读
  offCharacteristicReadRequest() {
    //已连接的设备请求读当前外围设备的特征值事件的回调函数
    BLEPeripheralServer.offCharacteristicReadRequest(function (res) {
      console.log(res);
    });
  },

  //网特征值写入数据，并通知已连接的主机 -- 处理走回包还是订阅·
  writeCharacteristicValue() {
    BLEPeripheralServer.writeCharacteristicValue({
      serviceId: '',
      characteristicId: '',
      value: '', //特征值对应的二进制值
      needNotify: true, //是否需要通知主机value已更新
      callbackId: '', //处理回包时使用
    });
  },

  //监听当前外围设备被连接或断开连接事件
  onBLEPeripheralConnectionStateChanged() {
    var that = this;
    console.log('监听外围设备动态');
    wx.onBLEPeripheralConnectionStateChanged((res) => {
      console.log(135, res);
    });
  },

  //取消监听  当前外围设备被连接或断开连接事件
  offBLEPeripheralConnectionStateChanged() {
    //console.log("执行取消监听")
    wx.offBLEPeripheralConnectionStateChanged(
      function (res) {
        //console.log(res)
      },
      function (err) {
        //console.log(err)
      }
    );
  },

  //移除服务
  removeService() {
    console.log('移除服务');
    BLEPeripheralServer.removeService({
      serviceId: '24DCCA9E-E50E-E0A9-0000-000000000000',
      success: function (res) {
        console.log(res);
      },
      fail: function (err) {
        console.log(err);
      },
    });
  },

  //获取蓝牙设备所有服务(service)。
  getBLEDeviceServices(deviceId) {
    var that = this;
    wx.getBLEDeviceServices({
      deviceId,
      success: (res) => {
        //获取设备服务中isPrimary为true的服务
        for (let i = 0; i < res.services.length; i++) {
          if (res.services[i].isPrimary) {
            //获取这个服务的特征值
            // that.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid)
            return;
          }
        }
      },
      fail(res) {
        console.error('22', res);
      },
    });
  },

  //获取蓝牙设备某个服务中所有特征值(characteristic)。
  getBLEDeviceCharacteristics(deviceId, serviceId) {
    var that = this;
    serviceId = '123456';
    wx.getBLEDeviceCharacteristics({
      deviceId, //:that.data.deviceId,//:'7F:E2:D9:F8:2D:00'
      serviceId, //:that.data.serviceId,//:'24DCCA9E-E50E-E0A9-0000-000000000000'
      success: (res) => {
        console.log(res.characteristics);
        console.log('getBLEDeviceCharacteristics success', res.characteristics);
        for (let i = 0; i < res.characteristics.length; i++) {
          let item = res.characteristics[i];
          if (item.properties.read) {
            wx.readBLECharacteristicValue({
              //读取低功耗蓝牙设备的特征值的二进制数据值
              deviceId,
              serviceId,
              characteristicId: item.uuid,
            });
          }
          if (item.properties.write) {
            //写入低功耗蓝牙设备的特征值的二进制数据值
            that.setData({
              canWrite: true,
              writeDeviceId: deviceId,
              writeServiceId: serviceId,
              writeCharacteristicId: item.uuid,
            });
          }
          if (item.properties.notify || item.properties.indicate) {
            wx.notifyBLECharacteristicValueChange({
              //启用低功耗蓝牙设备特征值变化时的 notify 功能
              deviceId,
              serviceId,
              characteristicId: item.uuid,
              state: true,
              success(res) {
                console.log('notifyBLECharacteristicValueChange success', res);
                // 操作之前先监听，保证第一时间获取数据
                wx.onBLECharacteristicValueChange((characteristic) => {
                  //处理蓝牙返回的数据
                  that.parseReturnData(characteristic.value);
                  console.log(
                    'notifyBLECharacteristicValueChange success',
                    characteristic.value
                  );
                });
              },
            });
          }
        }
      },
      fail(res) {
        console.error('getBLEDeviceCharacteristics', res);
      },
    });
  },

  //拼接硬件返回的分包数据
  parseReturnData(buf) {
    var that = this;
    var buf = new Int8Array(buf);
    //校验是不是首条包
    var isFirstPackage = checkCode(buf);
    var singleBag = Array.from(buf);
    if (isFirstPackage) {
      //
      that.data.cmd = singleBag[0];
      that.data.statusCode = singleBag[1];
      that.data.datalength = singleBag[2];
      if (that.data.datalength == 0) {
        //数据长度为0，说明没有数据
        that.data.checkSums = singleBag[singleBag.length - 1];
      }
      if (that.data.datalength > 0 && that.data.datalength <= 16) {
        //数据长度大于0，说明没有数据
        that.data.checkSums = singleBag[singleBag.length - 1];
        that.data.packData = singleBag.splice(3, singleBag.length - 4);
        that.data.datalength = 0;
      }
      if (that.data.datalength > 17) {
        //数据长度大于17，说明数据分包了
        that.data.packData = singleBag.splice(3, singleBag.length - 3);
        that.data.datalength -= 17; //数据长度减17
      }
    } else {
      if (that.data.datalength > 0) {
        if (that.data.datalength <= 19) {
          if (that.data.datalength == singleBag.length - 1) {
            //判断数据剩余长度与当前包的数据长度是否一致
            that.data.checkSums = singleBag[singleBag.length - 1];
            that.data.packData = that.data.packData.concat(
              singleBag.splice(0, singleBag.length - 1)
            );
            that.data.datalength = 0;
          } else {
            that.data.datalength = that.data.datalength - singleBag.length;
            that.data.packData = that.data.packData.concat(
              singleBag.splice(0, singleBag.length)
            );
          }
        } else {
          that.data.datalength -= singleBag.length; //数据长度减17
          that.data.packData = that.data.packData.concat(singleBag);
        }
      }
    }
    if (that.data.datalength == 0) {
      var data = ab2str(that.data.packData);
      console.log('返回值解析后:' + data);
      //把收到的数据解析出来展示在页面，方便测试
      that.showLog(
        that.data.cmd,
        that.data.statusCode,
        that.data.packData,
        that.data.checkSums
      );
      that.setData({
        packData: [], // 分包数据
        cmd: null, // 命令码
        statusCode: null, // 状态码
        datalength: null, // 数据长度
        checkSums: null, // 校验和
      });
    }
  },

  ///启用低功耗蓝牙设备特征值变化时的 notify 功能 -- 失败没有特征值
  notifyBLECharacteristicValueChange() {
    var that = this;
    wx.notifyBLECharacteristicValueChange({
      deviceId: that.data.deviceId,
      serviceId: that.data.uuid,
      characteristicId: that.data.uuid,
      state: true,
      success: function (res) {
        console.log(res);
      },
      fail: function (err) {
        console.log(err);
      },
    });
  },

  onBLECharacteristicValueChange: function () {
    var that = this;
    wx.onBLECharacteristicValueChange(function (res) {
      console.log('监听低功耗蓝牙设备的特征值变化事件成功');
      console.log(ab2hex(res.value));
      that.onBleDataAnalysic(ab2hex(res.value));
    });
  },

  //开始广播本地创建的外围设备
  startAdvertise() {
    var that = this;
    BLEPeripheralServer.startAdvertising({
      advertiseRequest: {
        connectable: true,
        deviceName: 'CBDevice',
        // manufacturerData: [{
        //   manufacturerId: '0xfff6',
        //   manufacturerSpecificData: toSendData.buffer
        // }],
        serviceUuids: ['24DCCA9E-E50E-E0A9-0000-000000000000'],
        connectable: true,
      }, //广播自定义参数
      powerLevel: 'low', //广播功率 -- 合法值 low ，medium，high
    })
      .then((res) => {
        console.log(res); //startBLEPeripheralAdvertising:ok
        // //执行监听
        that.onBLEPeripheralConnectionStateChanged();
        // //执行监听
        that.onCharacteristicWriteRequest();
        // //执行监听
        that.onCharacteristicReadRequest();
      })
      .catch((err) => {
        console.log(err);
      });
  },

  getModel: function () {
    //获取手机型号
    return global.state.sysinfo['model'];
  },

  getVersion: function () {
    //获取微信版本号
    return global.state.sysinfo['version'];
  },

  getSystem: function () {
    //获取操作系统版本
    return global.state.sysinfo['system'];
  },

  getPlatform: function () {
    //获取客户端平台
    return global.state.sysinfo['platform'];
  },

  getSDKVersion: function () {
    //获取客户端基础库版本
    return global.state.sysinfo['SDKVersion'];
  },

  //判断手机的平台以及版本 -- 如果是安卓需要大于6.0
  judgeOperationVersion() {
    //手机操作系统的版本号
    let andridVersionArr = this.getSystem().split(' ');
    let isAndrid = andridVersionArr.indexOf('Android') !== -1 ? true : false;
    let andridVersion = 0;
    if (andridVersionArr[1]) {
      if (andridVersionArr[1].indexOf('0') !== -1) {
        andridVersion = andridVersionArr[1].split('.')[0];
      } else {
        andridVersion = andridVersionArr[1];
      }
    }
    if (isAndrid && andridVersion < 6) {
      return false;
    } else {
      return true;
    }
  },

  ToHexString: function (r, t) {
    var e = Array.prototype.map.call(r, function (r) {
        return ('0' + r.toString(16)).slice(-2);
      }),
      n = '';
    if (null === t || void 0 === t) {
      t = '';
      var o = true,
        a = false,
        i = void 0;
      try {
        for (
          var l, u = e[Symbol.iterator]();
          !(o = (l = u.next()).done);
          o = true
        )
          n += l.value + t;
      } catch (r) {
        (a = true), (i = r);
      } finally {
        try {
          !o && u.return && u.return();
        } finally {
          if (a) throw i;
        }
      }
    } else {
      var c = true,
        f = false,
        y = void 0;
      try {
        for (
          var p, s = e[Symbol.iterator]();
          !(c = (p = s.next()).done);
          c = true
        )
          n += p.value + t;
      } catch (r) {
        (f = true), (y = r);
      } finally {
        try {
          !c && s.return && s.return();
        } finally {
          if (f) throw y;
        }
      }
      n = n.substr(0, n.length - 1);
    }
    return n.toUpperCase();
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad() {
    var that = this;
    wx.openBluetoothAdapter({
      mode: 'peripheral', //兼容iOS
      success: (res) => {
        //蓝牙已经开启了
        // wx.showToast({
        //   title: JSON.stringify(res),
        //   icon: 'none'
        // })
        //建立本地作为外围设备的服务端
        that.createBLEPeripheralServer();
      },
      fail: (err) => {
        //蓝牙未开启
        wx.showToast({ title: '请打开蓝牙', duration: 5000 });
        console.log(err);
      },
    });
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {
    this.runMarquee(); //textTips滚动条
  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {
    let that = this;
    that.closeBleConnection();
    // 页面显示
    let length = that.data.textTips.length * that.data.size; //文字长度
    let windowWidth = wx.getSystemInfoSync().windowWidth; //屏幕宽度
    that.setData({ marqueePace: 1, length, windowWidth });
    wx.openBluetoothAdapter({
      success(res) {
        console.log(res);
      },
      fail: (res) => {
        wx.showToast({ title: '请打开蓝牙', duration: 5000 });
      },
    });
  },

  closeBleConnection: function () {
    let that = this;
    wx.closeBLEConnection({
      deviceId: wx.getStorageSync('connectedDeviceId'),
      success(res) {
        wx.showToast({
          title: '当前已经断开与云锁蓝牙的连接',
          icon: 'none',
          duration: 2000,
        });
        wx.setStorageSync('connectedId', '');
        wx.setStorageSync('connectedDeviceId', '');
      },
    });
  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {},

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {
    this.setData({ marqueeInterval: 20 });
  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {
    this.onRefresh();
  },
  /**
   * 生命周期函数 下拉刷新
   */
  onRefresh: function () {
    //导航条加载动画
    wx.showNavigationBarLoading();
    //loading 提示框
    wx.showLoading({ title: '申请开锁中...', duration: 2000 });
    this.onLoad();
    console.log('下拉刷新啦');
    setTimeout(function () {
      wx.hideLoading();
      wx.hideNavigationBarLoading();
      //停止下拉刷新
      wx.stopPullDownRefresh();
    }, 2000);
  },
  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {},
  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {},
  dealHexString() {
    toSendData = new Uint8Array(
      hexString.match(/[\da-f]{2}/gi).map(function (h) {
        return parseInt(h, 16);
      })
    );
  },

  imageLoad: function (e) {
    //获取图片真实宽度
    var imgwidth = e.detail.width,
      imgheight = e.detail.height,
      //宽高比
      ratio = imgwidth / imgheight;
    //计算的高度值
    var viewHeight = app.getWindowWidth() / ratio;
    var imgheight = viewHeight;
    var imgheights = this.data.imgHeights;
    //把每一张图片的高度记录到数组里
    imgheights.push(imgheight);
    this.setData({ imgHeights: imgheights });
  },

  imageChange: function (e) {
    this.setData({ current: e.detail.current });
  },

  runMarquee: function () {
    let that = this;
    that.setData({ marqueeDistance: 0 });
    let marqueeInterval = setInterval(function () {
      if (-that.data.marqueeDistance < that.data.length - 100) {
        that.setData({
          marqueeDistance: that.data.marqueeDistance - that.data.marqueePace,
        });
      } else {
        clearInterval(marqueeInterval);
        that.setData({ marqueeDistance: 0 });
        that.runMarquee();
      }
    }, that.data.marqueeInterval);
  },
});
